from flask import request, Blueprint
import logging
import pandas as pd
from utils.database_util import save_gp
from utils.format_util import get_err_msg
from model.task import update_task
from common.config.config import ROOT_PATH
from gams import *

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")

gams = Blueprint('gams', __name__)

gms_folder = ROOT_PATH + "/gams/"


def run_simulate(ws, tih, tm, transfrslgov, job, status):
    # 当前个税：395.24，当前关税：2997.85，当前补贴：48.34
    out_params = ["VGDPS1", "EINVS1", "AVEVYH1", "EHS1", "YENTS1", "VMFS1", "VEFS1", "VMPS1", "VEPS1"]
    columns = ["类别", "GDP（亿元）", "投资总额（亿元）", "人均可支配收入（元）", "居民消费支出（亿元）", "企业收入（亿元）", "进口额（亿元）", "出口额（亿元）",
               "省际调入单位（亿元）", "省际调出单位（亿元）"]

    db = ws.add_database()
    tih_input = db.add_parameter("tih_input", 0)
    tm_input = db.add_parameter("tm_input", 0)
    transfrslgov_input = db.add_parameter("transfrslgov_input", 0)
    tih_input.add_record().value = tih
    tm_input.add_record().value = tm
    transfrslgov_input.add_record().value = transfrslgov

    opt = ws.add_options()
    opt.defines["gdxincname"] = db.name
    job.run(opt, databases=db)

    df = pd.DataFrame(columns=columns)
    df[columns[0]] = [status]
    for col, param in zip(columns[1:], out_params):
        for value in job.out_db[param]:
            df[col] = [value.value]
    return df


def run_simulate_inverse(ws, gdp, job, status, ext=""):
    # 当前gdp：52760.5
    out_params = ["Dtihs1", "Dtms1", "transfrslgovss1"]
    columns = ["类别"]
    column_tmp = [col + ext for col in ["个税（亿元）", "关税（亿元）", "补贴（亿元）"]]
    columns += column_tmp

    db = ws.add_database()
    gdp_input = db.add_parameter("gdp_input", 0)
    gdp_input.add_record().value = gdp

    opt = ws.add_options()
    opt.defines["gdxincname"] = db.name
    job.run(opt, databases=db)

    df = pd.DataFrame(columns=columns)
    df[columns[0]] = [status]
    for col, param in zip(columns[1:], out_params):
        for value in job.out_db[param]:
            df[col] = [value.value]
    return df


def simulate_inverse_module(gms_file, gdp, ext):
    ws = GamsWorkspace()
    job = ws.add_job_from_file(gms_file)

    df_before = run_simulate_inverse(ws, 0, job, "实际值", ext)
    df_after = run_simulate_inverse(ws, gdp, job, "期望值", ext)
    df = pd.concat([df_before, df_after], ignore_index=True)
    return df


def basic_simulate(is_new):
    params = request.form.to_dict()
    print(params)
    if params["tih"] == "":
        params["tih"] = 0
    tih = float(params["tih"])
    if params["tm"] == "":
        params["tm"] = 0
    tm = float(params["tm"])
    if params["transfrslgov"] == "":
        params["transfrslgov"] = 0
    transfrslgov = float(params["transfrslgov"])
    target = params["target"]
    taskId = params.get("taskId")

    if is_new:
        gms_file = gms_folder + "cge.gms"
    else:
        gms_file = gms_folder + "tih_down.gms"
        if tm != 0:
            gms_file = gms_folder + "tm.gms"
        if transfrslgov != 0:
            gms_file = gms_folder + "transfrslgov_down.gms"

    ws = GamsWorkspace()
    job = ws.add_job_from_file(gms_file)

    df_before = run_simulate(ws, 0, 0, 0, job, "实际值")
    df_after = run_simulate(ws, tih, tm, transfrslgov, job, "模拟值")
    df = pd.concat([df_before, df_after], ignore_index=True)
    saved = save_gp(target, df)
    updated = update_task(taskId, df, target, True)
    if saved and updated:
        logging.info(df)
        logging.info("success")
        return str({"status": "SUCCESS"})
    else:
        return get_err_msg()


@gams.route('/simulate', methods=['POST'])
def simulate():
    return basic_simulate(False)


@gams.route('/simulate_new', methods=['POST'])
def simulate_new():
    return basic_simulate(True)


@gams.route('/simulate_inverse', methods=['POST'])
def simulate_inverse():
    params = request.form.to_dict()
    print(params)
    if params["gdp"] == "":
        params["gdp"] = 0
    gdp = float(params["gdp"])
    target = params["target"]
    taskId = params.get("taskId")

    gms_file = gms_folder + "cge_inverse.gms"
    df1 = simulate_inverse_module(gms_file, gdp, "_路径1")

    gms_file2 = gms_folder + "cge_inverse2.gms"
    df2 = simulate_inverse_module(gms_file2, gdp, "_路径2")

    df = pd.merge(df1, df2, how='inner', on='类别')

    saved = save_gp(target, df)
    updated = update_task(taskId, df, target, True)
    if saved and updated:
        logging.info(df)
        logging.info("success")
        return str({"status": "SUCCESS"})
    else:
        return get_err_msg()
